import Axios from 'axios'
import { setting, axiosVariable, type CustomAxiosRequestConfig } from './setting'

const { t } = useI18n() // 国际化

/**
 * 生成每个请求唯一的键
 * @param {*} config
 * @returns string
 */
const getPendingKey = (config: CustomAxiosRequestConfig) => {
  let { url, method, params, data } = config
  let getParams = ''
  let urlPath = url
  if (url && url.indexOf('?') !== -1) {
    getParams = url.split('?')[1]
    urlPath = url.split('?')[0]
  }
  if (typeof data === 'string') data = JSON.parse(data) // response里面返回的config.data是个字符串对象
  const pendingInfo = {
    pendingKey: [urlPath, method, JSON.stringify(params), JSON.stringify(data), getParams].join('&'),
    pendingPath: [urlPath, method].join('&'),
    pendingParams: [JSON.stringify(params), JSON.stringify(data), getParams].join('&')
  }
  return pendingInfo
}

/**
 * 储存每个请求唯一值, 也就是cancel()方法, 用于取消请求
 * @param {*} config
 */
const addPending = (config: CustomAxiosRequestConfig) => {
  const pendingInfo = getPendingKey(config)
  config.cancelToken =
    config.cancelToken ||
    new Axios.CancelToken(cancel => {
      if (!axiosVariable.pendingMap.has(pendingInfo.pendingKey)) {
        axiosVariable.pendingMap.set(pendingInfo.pendingKey, cancel)
        axiosVariable.pendingList.push(pendingInfo)
      }
    })
}
/**
 * 删除请求对列中的请求
 * @param {*} config
 */
const removePending = (config: CustomAxiosRequestConfig) => {
  const pendingInfo = getPendingKey(config)
  if (axiosVariable.pendingMap.has(pendingInfo.pendingKey)) {
    const pendingKeyIndex = axiosVariable.pendingList.findIndex(item => item.pendingKey === pendingInfo.pendingKey)
    const cancelToken = axiosVariable.pendingMap.get(pendingInfo.pendingKey)
    const errorMsg = `${config.url}` + t('error', 'requestBreakOff')
    cancelToken(errorMsg, config)
    axiosVariable.pendingMap.delete(pendingInfo.pendingKey)
    axiosVariable.pendingList.splice(pendingKeyIndex, 1)
  }
}

/**
 * 清空所有请求
 */
const clearPending = () => {
  if (axiosVariable.pendingList.length > 0) {
    axiosVariable.pendingMap.forEach(function (cancel) {
      cancel()
    })
    axiosVariable.pendingMap.clear()
  }
  axiosVariable.pendingList = []
}

/**
 * 请求拦截中根据请求的可能类型，做不同的逻辑操作
 * @param {*} config
 */
const cacheRequest = (config: CustomAxiosRequestConfig) => {
  const pendingType = pendingRequestType(config)
  switch (pendingType) {
    case 'repeat':
      if (setting.is_request_disabled_repeat_enable && config.is_request_disabled_repeat_enable) {
        if (setting.request_repeat_in_type === 'last') {
          removePending(config)
          addPending(config)
        } else {
          let cancelFuc
          config.cancelToken = new Axios.CancelToken(cancel => {
            cancelFuc = cancel
          })

          const errorMsg = `${config.url}` + t('error', 'requestBreakOff')
          // 阻止当前请求
          cancelFuc(errorMsg, config)
        }
      } else {
        addPending(config)
      }
      break
    case 'filter':
      if (setting.is_request_disabled_repeat_enable && config.is_request_disabled_repeat_enable) {
        removePending(config)
      }
      addPending(config)
      break
    default:
      addPending(config)
      break
  }
}

// 判断请求类型
const pendingRequestType = (config: CustomAxiosRequestConfig) => {
  const pendingInfo = getPendingKey(config)
  let pendingType = 'normal'
  if (axiosVariable.pendingList.length > 0) {
    axiosVariable.pendingList.forEach(function (item) {
      // 请求地址、请求方法相同时
      if (item.pendingPath === pendingInfo.pendingPath) {
        if (item.pendingParams === pendingInfo.pendingParams) {
          pendingType = 'repeat' // 重复类型请求
        } else {
          pendingType = 'filter' // 筛选类多次请求
        }
      }
    })
  }
  return pendingType
}

export { cacheRequest, removePending, clearPending }
